<template>
  <view
    :id="'tab-' + vm.uid"
    ref="tabRef"
    class="ui-tab"
    :class="[
      props.ui,
      props.tpl,
      props.bg,
      props.align,
      { 'ui-tab-inline': props.inline },
      { 'ui-tab-scrolls': props.scroll },
    ]"
  >
    <block v-if="scroll">
      <view class="ui-tab-scroll-warp">
        <scroll-view
          scroll-x="true"
          class="ui-tab-scroll"
          :scroll-left="state.curValue > 1 ? state.tabNodeList[state.curValue - 1].left : 0"
          scroll-with-animation
          :style="{ width: `${state.content.width}px` }"
        >
          <view class="ss-flex ss-col-center">
            <su-tab-item
              v-for="(item, index) in props.tab"
              :key="index"
              :data="item"
              :index="index"
              @up="upitem"
              @tap.native="click(index, item)"
            ></su-tab-item>
            <view
              class="ui-tab-mark-warp"
              :class="[{ over: state.over }]"
              :style="[{ left: state.markLeft + 'px' }, { width: state.markWidth + 'px' }]"
            >
              <view
                class="ui-tab-mark"
                :class="[props.mark, { 'ui-btn': props.tpl == 'btn' || props.tpl == 'subtitle' }]"
                :style="[
                  {
                    background: props.tpl == 'btn' || props.tpl == 'subtitle' ? titleStyle.activeBg : 'none',
                  },
                ]"
              ></view>
            </view>
          </view>
        </scroll-view>
      </view>
    </block>
    <block v-else>
      <su-tab-item
        v-for="(item, index) in props.tab"
        :key="index"
        :data="item"
        :index="index"
        @up="upitem"
        @tap.native="click(index, item)"
      ></su-tab-item>
      <view
        class="ui-tab-mark-warp"
        :class="[{ over: state.over }]"
        :style="[{ left: state.markLeft + 'px' }, { width: state.markWidth + 'px' }]"
      >
        <view
          class="ui-tab-mark"
          :class="[props.mark, { 'ui-btn': props.tpl == 'btn' || props.tpl == 'subtitle' }]"
        ></view>
      </view>
    </block>
  </view>
</template>

<script>
export default {
  name: 'SuTab',
}
</script>

<script setup>
/**
 * 基础组件 - suTab
 */

import { toRef, ref, reactive, unref, onMounted, nextTick, getCurrentInstance, provide } from 'vue'
const vm = getCurrentInstance()

// 数据
const state = reactive({
  curValue: 0,
  tabNodeList: [],
  scrollLeft: 0,
  markLeft: 0,
  markWidth: 0,
  content: {
    width: 100,
  },
  over: false,
})

const tabRef = ref(null)
// 参数
const props = defineProps({
  modelValue: {
    type: Number,
    default: 0,
  },
  ui: {
    type: String,
    default: '',
  },
  bg: {
    type: String,
    default: '',
  },
  tab: {
    type: Array,
    default() {
      return []
    },
  },
  // line dot long,subtitle,trapezoid
  tpl: {
    type: String,
    default: 'line',
  },
  mark: {
    type: String,
    default: '',
  },
  align: {
    type: String,
    default: '',
  },
  curColor: {
    type: String,
    default: 'ui-TC',
  },
  defaultColor: {
    type: String,
    default: 'ui-TC',
  },
  scroll: {
    type: Boolean,
    default: false,
  },
  inline: {
    type: Boolean,
    default: false,
  },
  titleStyle: {
    type: Object,
    default: () => ({
      activeBg: '#DA2B10',
      activeColor: '#FEFEFE',
      color: '#D70000',
    }),
  },
  subtitleStyle: {
    type: Object,
    default: () => ({
      activeColor: '#333',
      color: '#C42222',
    }),
  },
})

const emits = defineEmits(['update:modelValue', 'change'])

onMounted(() => {
  state.curValue = props.modelValue
  setCurValue(props.modelValue)
  nextTick(() => {
    computedQuery()
  })
  uni.onWindowResize((res) => {
    computedQuery()
  })
})

const computedQuery = () => {
  uni
    .createSelectorQuery()
    .in(vm)
    .select('#tab-' + vm.uid)
    .boundingClientRect((data) => {
      if (data != null) {
        if (data.left == 0 && data.right == 0) {
          // setTimeout(() => {
          computedQuery()
          // }, 300);
        } else {
          state.content = data
          setTimeout(() => {
            state.over = true
          }, 300)
        }
      } else {
        console.log('tab-' + vm.uid + ' data error')
      }
    })
    .exec()
}

const setCurValue = (value) => {
  if (value == state.curValue) return
  state.curValue = value
  computedMark()
}

const click = (index, item) => {
  setCurValue(index)
  emits('update:modelValue', index)
  emits('change', {
    index: index,
    data: item,
  })
}

const upitem = (index, e) => {
  state.tabNodeList[index] = e
  if (index == state.curValue) {
    computedMark()
  }
}

const computedMark = () => {
  if (state.tabNodeList.length == 0) return
  let left = 0
  let list = unref(state.tabNodeList)
  let cur = state.curValue
  state.markLeft = list[cur].left - state.content.left
  state.markWidth = list[cur].width
}

const computedScroll = () => {
  if (state.curValue == 0 || state.curValue == state.tabNodeList.length - 1) {
    return false
  }
  let i = 0
  let left = 0
  let list = state.tabNodeList
  for (i in list) {
    if (i == state.curValue && i != 0) {
      left = left - list[i - 1].width
      break
    }
    left = left + list[i].width
  }
  state.scrollLeft = left
}

provide('suTabProvide', {
  props,
  curValue: toRef(state, 'curValue'),
})
</script>

<style lang="scss">
.ui-tab {
  position: relative;
  display: flex;
  height: 4em;
  align-items: center;

  &.ui-tab-scrolls {
    width: 100%;
    /* #ifdef MP-WEIXIN */
    padding-bottom: 10px;
    /* #endif */
    .ui-tab-scroll-warp {
      overflow: hidden;
      height: inherit;
      width: 100%;
      .ui-tab-scroll {
        position: relative;
        display: block;
        white-space: nowrap;
        overflow: auto;
        min-height: 4em;
        line-height: 4em;
        width: 100% !important;
        .ui-tab-mark-warp {
          display: flex;
          align-items: top;
          justify-content: center;
          .ui-tab-mark.ui-btn {
            /* #ifndef MP-WEIXIN */
            height: 2em;
            width: calc(100% - 0.6em);
            margin-top: 4px;
            /* #endif */
            /* #ifdef MP-WEIXIN */
            height: 2em;
            width: calc(100% - 0.6em);
            margin-top: 4px;
            /* #endif */
          }
        }
      }
    }
  }

  .ui-tab-mark-warp {
    color: inherit;
    position: absolute;
    top: 0;
    height: 100%;
    z-index: 0;

    &.over {
      transition: 0.3s;
    }

    .ui-tab-mark {
      color: var(--ui-BG-Main);
      height: 100%;
    }
  }

  &.line {
    .ui-tab-mark {
      border-bottom: 2px solid currentColor;
    }
  }

  &.topline {
    .ui-tab-mark {
      border-top: 2px solid currentColor;
    }
  }

  &.dot {
    .ui-tab-mark::after {
      content: '';
      width: 0.5em;
      height: 0.5em;
      background-color: currentColor;
      border-radius: 50%;
      display: block;
      position: absolute;
      bottom: 0.3em;
      left: 0;
      right: 0;
      margin: auto;
    }
  }

  &.long {
    .ui-tab-mark::after {
      content: '';
      width: 2em;
      height: 0.35em;
      background-color: currentColor;
      border-radius: 5em;
      display: block;
      position: absolute;
      bottom: 0.3em;
      left: 0;
      right: 0;
      margin: auto;
    }
  }

  &.trapezoid {
    .ui-tab-mark::after {
      content: '';
      width: calc(100% - 2em);
      height: 0.35em;
      background-color: currentColor;
      border-radius: 5em 5em 0 0;
      display: block;
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
    }
  }

  &.btn {
    .ui-tab-mark-warp {
      display: flex;
      align-items: center;
      justify-content: center;

      .ui-tab-mark.ui-btn {
        height: calc(100% - 1.6em);
        width: calc(100% - 0.6em);
      }
    }

    &.sm .ui-tab-mark.ui-btn {
      height: calc(100% - 2px);
      width: calc(100% - 2px);
      border-radius: #{$radius - 2};
    }
  }

  &.subtitle {
    .ui-tab-mark-warp {
      display: flex;
      align-items: top;
      justify-content: center;
      padding-top: 0.6em;

      .ui-tab-mark.ui-btn {
        height: calc(100% - 2.8em);
        width: calc(100% - 0.6em);
      }
    }
  }

  &.ui-tab-inline {
    display: inline-flex;
    height: 3.5em;

    &.ui-tab-scrolls {
      .ui-tab-scroll {
        height: calc(3.5em + 17px);
        line-height: 3.5em;

        .ui-tab-mark-warp {
          height: 3.5em;
        }
      }
    }

    &.btn {
      .ui-tab-mark-warp {
        .ui-tab-mark.ui-btn {
          height: calc(100% - 10px);
          width: calc(100% - 10px);
        }
      }
    }
  }

  &.sm {
    height: 70rpx !important;

    &.ui-tab-inline {
      height: 70rpx;

      &.ui-tab-scrolls {
        .ui-tab-scroll {
          height: calc(70rpx + 17px);
          line-height: 70rpx;

          .ui-tab-mark-warp {
            height: 70rpx;
          }
        }
      }

      &.btn .ui-tab-mark.ui-btn {
        height: calc(100% - 2px);
        width: calc(100% - 2px);
        border-radius: #{$radius - 2};
      }
    }
  }
}
</style>
